package com.neborosoft.FlyingDog.logic.search.navigation;

import com.neborosoft.FlyingDog.logic.search.SearchResult;
import com.neborosoft.lib.collections.list.NavigationList;
import com.neborosoft.lib.handlers.ErrorListener;
import com.neborosoft.lib.threading.AbstractAsyncTask;
import com.neborosoft.lib.threading.OnHostThreadExecutor;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;

/**
 * Created with IntelliJ IDEA.
 * User: CM
 * Date: 06.01.13
 * Time: 20:35
 * To change this template use File | Settings | File Templates.
 */
public abstract class SearchNavigationList<T> extends NavigationList<T>{
    private ErrorListener errorListener;
    private Executor executor;
    private OnHostThreadExecutor onHostThreadExecutor;

    protected SearchNavigationList(List<T> initialElements,
                                   Executor executor,
                                   OnHostThreadExecutor onHostThreadExecutor,
                                   int maxElementsCount)
    {
        super(initialElements, maxElementsCount);
        this.executor = executor;
        this.onHostThreadExecutor = onHostThreadExecutor;
    }

    @Override
    protected void getElementsOfPage(final int pageNumber,
                                     final OnPageLoadingFinished<T> onPageLoadingFinished)
    {
        AbstractAsyncTask<Void,SearchResult<T>> asyncTask =
                new AbstractAsyncTask<Void, SearchResult<T>>(onHostThreadExecutor)
        {
            @Override
            protected SearchResult<T> doInBackground(Void params) {
                try {
                    if(isAllDataLoaded()){
                        return null;
                    }
                    SearchResult<T> result = search(pageNumber);
                    if(result.elements == null){
                        throw new NullPointerException();
                    }
                    return result;
                }
                catch (Exception e) {
                    if(errorListener != null){
                        errorListener.onError(e);
                    }

                    SearchResult<T> searchResult = new SearchResult<T>();
                    searchResult.elements = Collections.emptyList();
                    searchResult.isLastPage = true;
                    return searchResult;
                }
            }

            @Override
            protected void onPostExecute(SearchResult<T> searchResult) {
                if (searchResult != null) {
                    onPageLoadingFinished.onLoadingFinished(searchResult.elements, searchResult.isLastPage);
                }
            }
        };

        asyncTask.execute(executor);
    }

    public ErrorListener getErrorListener() {
        return errorListener;
    }

    public void setErrorListener(ErrorListener errorListener) {
        this.errorListener = errorListener;
    }

    protected abstract SearchResult<T> search(int pageNumber) throws Exception;
}
